package icu.groot.alan.util;

import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class Dao {

    /**
     * driver JDBC连接方式
     */
    private static final String driver;
    /**
     * url 连接数据库的地址
     */
    private static final String url;
    /**
     * user 连接数据库的用户名
     */
    private static final String user;
    /**
     * password 连接数据库的密码
     */
    private static final String password;
    //静态代码块:随着类的加载而执行，而且只执行一次
    //加载配置文件
    static {
        InputStream ras = Dao.class.getClassLoader().getResourceAsStream("db.properties");
        Properties properties = new Properties();
        try {
            properties.load(ras);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("BaseDao -- static -- 读取静态资源出错");
        }
        driver = properties.getProperty("jdbc.driver");
        url = properties.getProperty("jdbc.url");
        user = properties.getProperty("jdbc.user");
        password = properties.getProperty("jdbc.password");
    }
    /**
     * @method getConnection
     * @description 获取数据库连接
     * @return 返回数据库连接
     */
    public static Connection getConnection() {
        Connection connection = null;
        try {
            //加载数据库驱动
            Class.forName(driver);
            //获取数据库连接
            connection = DriverManager.getConnection(url, user, password);
            //手动提交事务
            connection.setAutoCommit(false);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            System.out.println("BaseDao -- getConnection -- 数据库驱动加载失败");
        } catch (SQLException e){
            e.printStackTrace();
            System.out.println("BaseDao -- getConnection -- 获取数据库连接失败");
        }
        return connection;
    }
    /**
     * @method execute
     * @description 编写查询(R)公共类
     * @param connection 数据库连接
     * @param preparedStatement 预编译SQL语句
     * @param resultSet 查询结果数据集
     * @param sql SQL语句
     * @param params SQL语句参数
     * @return 返回查询的数据集
     * @throws SQLException 数据库操作异常
     */
    public static ResultSet execute(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet, String sql, Object[] params) throws SQLException {
        //创建时绑定sql模板
        preparedStatement =connection.prepareStatement(sql);
        for (int i = 0; i < params.length; i++) {
            //向sql里面的?占位符添加params里面的内容，占位符的下标1开始
            preparedStatement.setObject(i + 1, params[i]);
        }
        System.out.println("sql: " + preparedStatement);
        //获取查询的结果集
        resultSet = preparedStatement.executeQuery();
        return resultSet;
    }
    /**
     * @method execute
     * @description 编写增删改(CUD)公共类
     * @param connection 数据库连接
     * @param preparedStatement 预编译SQL语句
     * @param sql SQL语句
     * @param params SQL语句参数
     * @return 返回受影响记录条数
     * @throws SQLException 数据库操作异常
     */
    public static int execute(Connection connection, PreparedStatement preparedStatement, String sql, Object[] params) throws SQLException {
        //创建时绑定sql模板
        preparedStatement = connection.prepareStatement(sql);
        for (int i = 0; i < params.length; i++) {
            //向sql里面的?占位符添加params里面的内容，占位符的下标1开始
            preparedStatement.setObject(i + 1, params[i]);
        }
        System.out.println("sql: " + preparedStatement);
        return preparedStatement.executeUpdate();
    }
    public static boolean closeResource(Connection connection){
        return closeResource(connection, null, null);
    }

    public static boolean closeResource(PreparedStatement preparedStatement){
        return closeResource(preparedStatement, null);
    }

    public static boolean closeResource(PreparedStatement preparedStatement, ResultSet resultSet){
        return closeResource(null, preparedStatement, resultSet);
    }

    /**
     * @method closeResource
     * @description 关闭资源公共类
     * @param connection 数据库连接的资源
     * @param preparedStatement 预编译SQL语句的资源
     * @param resultSet 数据结果集的资源
     * @return 资源是否关闭成功
     */
    public static boolean closeResource(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet){
        boolean flag = true;
        if (connection != null){
            try {
                connection.close();
                //System.gc()函数的作用是提醒或告诉虚拟机，希望进行一次垃圾回收。
                System.gc();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
                flag = false;
                System.out.println("BaseDao -- closeResource -- connection资源关闭失败");
            }
        }
        if (preparedStatement != null){
            try {
                preparedStatement.close();
                //System.gc()函数的作用是提醒或告诉虚拟机，希望进行一次垃圾回收。
                System.gc();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
                flag = false;
                System.out.println("BaseDao -- closeResource -- preparedStatement资源关闭失败");
            }
        }
        if (resultSet != null){
            try {
                resultSet.close();
                //System.gc()函数的作用是提醒或告诉虚拟机，希望进行一次垃圾回收。
                System.gc();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
                flag = false;
                System.out.println("BaseDao -- closeResource -- resultSet资源关闭失败");
            }
        }
        return flag;
    }
}
